package com.coder.bike.security.handler;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWTPayload;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

import com.coder.bike.security.AuthUser;
import com.coder.bike.security.AuthenticationResult;
import com.coder.bike.utils.JwtUtils;
import com.coder.bike.utils.RedisUtils;
import com.coder.bike.utils.ResultCode;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Resource
    private RedisUtils redisUtils;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication)
            throws IOException {
        //设置客户端的响应的内容类型是json
        response.setContentType("application/json;charset=utf-8");
        AuthUser user = (AuthUser) authentication.getPrincipal();
        // 从认证信息中提取用户对象
        // 准备token相关数据并生成token
        Map<String, Object> map = new HashMap<>();
        map.put("username", user.getUsername());
        map.put("userid", user.getId());
        map.put("userType", user.getUserType());
        String token = JwtUtils.createToken(map);
        // 解析token获取过期时间，并构建认证结果对象
        NumberWithFormat claim = (NumberWithFormat)
                JwtUtils.parseToken(token).getClaim(JWTPayload.EXPIRES_AT);
        long expireTime = Convert.toDate(claim).getTime();
        AuthenticationResult authenticationResult
                = new AuthenticationResult(user.getId(), ResultCode.SUCCESS, user.getUserType(),token, expireTime);
        // 将认证结果转换为JSON字符串
        String result = JSON.toJSONString(authenticationResult,
                SerializerFeature.DisableCircularReferenceDetect);
        //获取输出流
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(result.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
        // 将token存入Redis，设置过期时间
        String tokenKey = "token:" + token;
        long nowTime = DateTime.now().getTime();
        redisUtils.set(tokenKey, token, (expireTime - nowTime) / 1000);
    }
}